/*     */ package com.zimbra.cs.util;
/*     */ 
/*     */ import com.zimbra.common.account.ZAttrProvisioning.ShareNotificationMtaConnectionType;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.StringUtil;
/*     */ import com.zimbra.common.util.TimeoutMap;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.mailclient.smtp.SmtpTransport;
/*     */ import com.zimbra.cs.mailclient.smtp.SmtpsTransport;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collections;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Properties;
/*     */ import javax.mail.Authenticator;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.NoSuchProviderException;
/*     */ import javax.mail.PasswordAuthentication;
/*     */ import javax.mail.Session;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class JMSession
/*     */ {
/*     */   public static final String SMTP_SEND_PARTIAL_PROPERTY = "mail.smtp.sendpartial";
/*     */   public static final String SMTPS_SEND_PARTIAL_PROPERTY = "mail.smtps.sendpartial";
/*     */   private static final Session sSession;
/*     */   
/*     */   static
/*     */   {
/*  60 */     System.setProperty("mail.mime.base64.ignoreerrors", "true");
/*     */     
/*  62 */     Properties props = new Properties();
/*  63 */     props.setProperty("mail.mime.address.strict", "false");
/*  64 */     sSession = Session.getInstance(props);
/*  65 */     setProviders(sSession);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void setProviders(Session session)
/*     */   {
/*  74 */     if (LC.javamail_zsmtp.booleanValue()) {
/*     */       try {
/*  76 */         session.setProvider(SmtpTransport.PROVIDER);
/*  77 */         session.setProvider(SmtpsTransport.PROVIDER);
/*     */       } catch (NoSuchProviderException e) {
/*  79 */         if (!$assertionsDisabled) { throw new AssertionError();
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static Session getSession()
/*     */   {
/*  89 */     return sSession;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static Session getSmtpSession()
/*     */     throws MessagingException
/*     */   {
/*  97 */     return getSmtpSession((Domain)null);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static Session getSmtpSession(Account account)
/*     */     throws MessagingException
/*     */   {
/* 105 */     Domain domain = null;
/* 106 */     if (account != null) {
/*     */       try {
/* 108 */         domain = Provisioning.getInstance().getDomain(account);
/*     */       } catch (ServiceException e) {
/* 110 */         ZimbraLog.smtp.warn("Unable to look up domain for account %s.", account.getName(), e);
/*     */       }
/*     */     }
/*     */     
/* 114 */     Session session = getSmtpSession(domain);
/* 115 */     if ((account != null) && (account.isSmtpEnableTrace())) {
/* 116 */       session.setDebug(true);
/*     */     }
/* 118 */     return session;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private static Session getSmtpSession(Domain domain)
/*     */     throws MessagingException
/*     */   {
/*     */     Server server;
/*     */     
/*     */ 
/*     */     try
/*     */     {
/* 131 */       server = Provisioning.getInstance().getLocalServer();
/*     */     } catch (ServiceException e) {
/* 133 */       throw new MessagingException("Unable to initialize JavaMail session", e);
/*     */     }
/*     */     
/* 136 */     Properties props = getJavaMailSessionProperties(server, domain);
/* 137 */     Session session = Session.getInstance(props);
/* 138 */     setProviders(session);
/* 139 */     if (LC.javamail_smtp_debug.booleanValue()) {
/* 140 */       session.setDebug(true);
/*     */     }
/* 142 */     return session;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public static Session getRelaySession()
/*     */     throws MessagingException
/*     */   {
/* 151 */     Provisioning prov = Provisioning.getInstance();
/*     */     
/* 153 */     String relayHost = null;
/*     */     Server server;
/*     */     int relayPort;
/*     */     boolean useSmtpAuth;
/*     */     boolean useTls;
/*     */     try {
/* 159 */       server = prov.getLocalServer();
/* 160 */       relayHost = server.getShareNotificationMtaHostname();
/* 161 */       relayPort = server.getShareNotificationMtaPort();
/* 162 */       useSmtpAuth = server.isShareNotificationMtaAuthRequired();
/* 163 */       useTls = server.getShareNotificationMtaConnectionType() == ZAttrProvisioning.ShareNotificationMtaConnectionType.STARTTLS;
/*     */     } catch (ServiceException e) {
/* 165 */       throw new MessagingException("Unable to identify local server", e);
/*     */     }
/* 167 */     if ((relayHost == null) || (relayPort == 0)) {
/* 168 */       return getSmtpSession();
/*     */     }
/*     */     
/* 171 */     Properties props = getJavaMailSessionProperties(server, null);
/* 172 */     props.setProperty("mail.smtp.host", relayHost);
/* 173 */     props.setProperty("mail.smtp.port", "" + relayPort);
/* 174 */     Authenticator auth = null;
/*     */     
/* 176 */     if (useSmtpAuth) {
/* 177 */       String account = server.getShareNotificationMtaAuthAccount();
/* 178 */       String password = server.getShareNotificationMtaAuthPassword();
/* 179 */       if ((account == null) || (password == null)) {
/* 180 */         ZimbraLog.smtp.warn("zimbraShareNotificationMtaAuthRequired is enabled but account or password is unset");
/*     */       } else {
/* 182 */         props.setProperty("mail.smtp.auth", "" + useSmtpAuth);
/* 183 */         props.setProperty("mail.smtp.sasl.enable", "" + useSmtpAuth);
/* 184 */         auth = new SmtpAuthenticator(account, password);
/*     */       }
/*     */     }
/*     */     
/* 188 */     if (useTls) {
/* 189 */       props.setProperty("mail.smtp.starttls.enable", "" + useTls);
/*     */     }
/*     */     
/* 192 */     Session session = auth == null ? Session.getInstance(props) : Session.getInstance(props, auth);
/* 193 */     setProviders(session);
/* 194 */     if (LC.javamail_smtp_debug.booleanValue()) {
/* 195 */       session.setDebug(true);
/*     */     }
/* 197 */     return session;
/*     */   }
/*     */   
/*     */   private static class SmtpAuthenticator extends Authenticator {
/*     */     private final String username;
/*     */     private final String password;
/*     */     
/* 204 */     public SmtpAuthenticator(String username, String password) { this.username = username;this.password = password;
/*     */     }
/*     */     
/*     */     protected PasswordAuthentication getPasswordAuthentication() {
/* 208 */       return new PasswordAuthentication(this.username, this.password);
/*     */     }
/*     */   }
/*     */   
/*     */   private static Properties getJavaMailSessionProperties(Server server, Domain domain) throws MessagingException {
/* 213 */     String smtpHost = null;
/*     */     try
/*     */     {
/* 216 */       smtpHost = getRandomSmtpHost(domain);
/*     */     } catch (ServiceException e) {
/* 218 */       throw new MessagingException("Unable to initialize JavaMail session", e);
/*     */     }
/* 220 */     if (smtpHost == null) {
/* 221 */       String msg = "No SMTP hosts available";
/* 222 */       if (domain != null) {
/* 223 */         msg = msg + " for domain " + domain.getName();
/*     */       }
/* 225 */       throw new MessagingException(msg);
/*     */     }
/* 227 */     Properties props = new Properties(sSession.getProperties());
/* 228 */     props.setProperty("mail.smtp.host", smtpHost);
/* 229 */     props.setProperty("mail.smtp.port", getValue(server, domain, "zimbraSmtpPort"));
/* 230 */     props.setProperty("mail.smtp.localhost", LC.zimbra_server_hostname.value());
/*     */     
/*     */ 
/* 233 */     String sTimeout = getValue(server, domain, "zimbraSmtpTimeout");
/* 234 */     long timeout = sTimeout == null ? 60L : Long.parseLong(sTimeout);
/* 235 */     sTimeout = Long.toString(timeout * 1000L);
/* 236 */     props.setProperty("mail.smtp.connectiontimeout", sTimeout);
/* 237 */     props.setProperty("mail.smtp.timeout", sTimeout);
/*     */     
/* 239 */     Boolean sendPartial = Boolean.valueOf(Boolean.parseBoolean(getValue(server, domain, "zimbraSmtpSendPartial")));
/* 240 */     props.setProperty("mail.smtp.sendpartial", sendPartial.toString());
/* 241 */     props.setProperty("mail.smtps.sendpartial", sendPartial.toString());
/*     */     
/*     */ 
/* 244 */     if (domain != null) {
/* 245 */       props.setProperty("mail.host", domain.getName());
/*     */     }
/*     */     
/* 248 */     return props;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private static String getValue(Server server, Domain domain, String attrName)
/*     */   {
/* 255 */     String value = null;
/* 256 */     if (domain != null) {
/* 257 */       value = domain.getAttr(attrName);
/*     */     }
/* 259 */     if (StringUtil.isNullOrEmpty(value)) {
/* 260 */       return server.getAttr(attrName);
/*     */     }
/* 262 */     return value;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 269 */   private static Map<String, Object> sBadSmtpHosts = Collections.synchronizedMap(new TimeoutMap(LC.smtp_host_retry_millis.intValue()));
/*     */   
/*     */   public static void resetSmtpHosts()
/*     */   {
/* 273 */     ZimbraLog.smtp.debug("Resetting bad SMTP hosts.");
/* 274 */     sBadSmtpHosts.clear();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static String getRandomSmtpHost(Domain domain)
/*     */     throws ServiceException
/*     */   {
/* 285 */     List<String> hostList = getSmtpHosts(domain);
/* 286 */     if (hostList.size() > 0) {
/* 287 */       return (String)hostList.get(0);
/*     */     }
/* 289 */     return null;
/*     */   }
/*     */   
/*     */   private static boolean isHostBad(String hostname) {
/* 293 */     if (hostname != null) {
/* 294 */       hostname = hostname.toLowerCase();
/*     */     }
/* 296 */     return sBadSmtpHosts.containsKey(hostname);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static List<String> getSmtpHosts(Domain domain)
/*     */     throws ServiceException
/*     */   {
/* 304 */     List<String> hosts = new ArrayList();
/* 305 */     for (String host : lookupSmtpHosts(domain)) {
/* 306 */       if (!isHostBad(host)) {
/* 307 */         hosts.add(host);
/*     */       }
/*     */     }
/* 310 */     Collections.shuffle(hosts);
/* 311 */     return hosts;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void markSmtpHostBad(String hostName)
/*     */   {
/* 322 */     if (hostName == null) {
/* 323 */       return;
/*     */     }
/* 325 */     ZimbraLog.smtp.info("Disallowing connections to %s for %d milliseconds.", new Object[] { hostName, Integer.valueOf(LC.smtp_host_retry_millis.intValue()) });
/*     */     
/* 327 */     sBadSmtpHosts.put(hostName.toLowerCase(), null);
/*     */   }
/*     */   
/* 330 */   private static final String[] NO_HOSTS = new String[0];
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static String[] lookupSmtpHosts(Domain domain)
/*     */     throws ServiceException
/*     */   {
/* 340 */     String[] hosts = NO_HOSTS;
/* 341 */     if (domain != null) {
/* 342 */       hosts = domain.getSmtpHostname();
/*     */     }
/* 344 */     if (hosts.length == 0) {
/* 345 */       Server server = Provisioning.getInstance().getLocalServer();
/* 346 */       hosts = server.getSmtpHostname();
/*     */     }
/* 348 */     return hosts;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/util/JMSession.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */